﻿using Faser_Shop.Models.Configs;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using System;
using Microsoft.AspNetCore.Http;
using Newtonsoft.Json.Linq;
using System.Linq;

namespace Faser_Shop.Services
{
    /// <summary>
    /// 认证处理接口
    /// </summary>
    public interface IJWTService
    {
        // 创建Token
        string CreateToken(int userId);
        // 从Token中获取用户信息
        int GetUserIdFromToken(string token);

        int GetUserId(HttpContext context);
    }

    /// <summary>
    /// 认证处理服务
    /// </summary>
    public class JWTService : IJWTService
    {
        private readonly JWTConfig _jwtConfig;

        public JWTService(IOptions<JWTConfig> jwtConfig)
        {
            this._jwtConfig = jwtConfig.Value;
        }

        public string GenerateToken(Claim[] claims)
        {
            //创建密钥
            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_jwtConfig.Secret));
            //密钥加密
            var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
            //token配置
            var jwtToken = new JwtSecurityToken(_jwtConfig.Issuer,
                _jwtConfig.Audience,
                claims,
                expires: DateTime.Now.AddMinutes(_jwtConfig.AccessExpiration),
                signingCredentials: credentials);

            //获取token
            var token = new JwtSecurityTokenHandler().WriteToken(jwtToken);
            return token;
        }

        public string CreateToken(int userId)
        {
            var claims = new[] {
                new Claim(ClaimTypes.NameIdentifier, userId.ToString()),
                new Claim(ClaimTypes.Role, "User")
            };

            return GenerateToken(claims);
        }

        public string CreateAdminToken(int userId)
        {
            var claims = new[]
            {
                new Claim(ClaimTypes.NameIdentifier, userId.ToString()),
                new Claim(ClaimTypes.Role, "Admin")
            };

            return GenerateToken(claims);
        }

        public int GetUserIdFromToken(string token)
        {
            var jwtHandler = new JwtSecurityTokenHandler();
            var jwtToken = jwtHandler.ReadJwtToken(token);
            var userId = jwtToken.Claims.First(claim => claim.Type == ClaimTypes.NameIdentifier).Value;

            var userIdInt = 0;
            if (!int.TryParse(userId, out userIdInt))
            {
                throw new Exception("Token中的用户ID类型无法转换为Int");
            }
            return userIdInt;
        }

        public int GetUserId(HttpContext context)
        {
            var userId = context.User.Claims.FirstOrDefault(x => x.Type == ClaimTypes.NameIdentifier).Value;
            var userIdInt = 0;
            if (!int.TryParse(userId, out userIdInt))
            {
                throw new Exception("Token中的用户ID类型无法转换为Int");
            }
            return userIdInt;
        }
    }
}
